package com.example.mvn.demo.configuration;

import com.example.mvn.demo.annotions.RewriteController;
import org.springframework.aop.support.AopUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhouzeng
 * @date 2019/4/23
 */
public class RewriteRequestMappingHandler extends RequestMappingHandlerMapping {

    private static Set<String> rewriteControllerBeanNames = new HashSet<>();

    @Override
    protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {

        RequestMappingInfo mappingForMethod = super.getMappingForMethod(method, handlerType);

        if (handlerType.isAnnotationPresent(RewriteController.class)) {
            // We have a super class controller.
            return mappingForMethod;
        } else {
            // We do not have a super class, therefore we need to look for other implementations of this class.
            if (CollectionUtils.isEmpty(rewriteControllerBeanNames)) {
                Map<String, Object> rewriteControllerBeans = getApplicationContext().getBeansWithAnnotation(RewriteController.class);
                rewriteControllerBeanNames.addAll(rewriteControllerBeans.entrySet()
                    .stream().map(e -> AopUtils.getTargetClass(e.getValue()).getSuperclass().getName()).collect(Collectors.toList()));
            }
            Boolean isExist = rewriteControllerBeanNames.contains(handlerType.getName());
            if (!isExist) {
                // No classes extend this handler, therefore it is the only one.
                return mappingForMethod;
            }
            // Classes extend this handler,
            return null;
        }
    }
}
